/*
    PhotoFlip, a free 3d photo managment suite.
    Copyright (C) 2007  Elisée MAURER, Gaétan WALTER
    
    This file is part of PhotoFlip.
    Contact: http://www.photoflip.org/

    PhotoFlip is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PhotoFlip is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PhotoFlip.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "photoflip.hpp"

#include <iostream>

photoflip::photoflip(Glib::RefPtr<Gnome::Glade::Xml> refXml): m_gl(&m_lib) {
	refXml->get_widget("mainWindow", m_mainWindow);
	
	if(!m_mainWindow)
		throw std::runtime_error("Couldn't find mainWindow in photoflip.glade");
	
	// menu bar
	Gtk::MenuItem *menuItemImport, *menuItemQuit, *menuItemCut, *menuItemCopy,
		*menuItemDelete, *menuItemAbout;
	
	refXml->get_widget("menuBar", m_menuBar);
	
	// (file menu)
	refXml->get_widget("menuItemImport", menuItemImport);
	menuItemImport->signal_activate().connect(sigc::mem_fun(*this, &photoflip::fileImport));
	refXml->get_widget("fileImportDialog", m_fileImportDialog);
	m_fileImportDialog->signal_response().connect(sigc::mem_fun(*this, &photoflip::fileImportResponse));
	
	refXml->get_widget("menuItemQuit", menuItemQuit);
	menuItemQuit->signal_activate().connect(sigc::mem_fun(*this, &photoflip::quit));
	
	// (view menu)
	refXml->get_widget("menuItemFullscreen", m_menuItemFullscreen);
	m_menuItemFullscreen->signal_toggled().connect(sigc::mem_fun(*this, &photoflip::menuFullscreen));
	
	refXml->get_widget("menuItemShowControls", m_menuItemShowControls);
	m_menuItemShowControls->signal_activate().connect(sigc::mem_fun(*this, &photoflip::showControls));
	
	refXml->get_widget("menuItemShowFrames", m_menuItemShowFrames);
	
	m_menuItemShowFrames->signal_toggled().connect(sigc::mem_fun(*this, &photoflip::showFrames));
	
	// (photo menu)
	refXml->get_widget("menuItemCut", menuItemCut);
	menuItemCut->signal_activate().connect(sigc::bind(sigc::mem_fun(m_gl, &GLArea::moveToBasket), -1));
	
	refXml->get_widget("menuItemCopy", menuItemCopy);
	menuItemCopy->signal_activate().connect(sigc::bind(sigc::mem_fun(m_gl, &GLArea::copyToBasket), -1));
	
	refXml->get_widget("menuItemDelete", menuItemDelete);
	menuItemDelete->signal_activate().connect(sigc::mem_fun(*this, &photoflip::deletePhoto));
	refXml->get_widget("photoDeletionDialog", m_photoDeletionDialog);
	m_photoDeletionDialog->signal_response().connect(sigc::mem_fun(*this, &photoflip::deletePhotoResponse));
	
	// (help menu)
	refXml->get_widget("menuItemAbout", menuItemAbout);
	menuItemAbout->signal_activate().connect(sigc::mem_fun(*this, &photoflip::about));
	refXml->get_widget("aboutDialog", m_aboutDialog);
	m_aboutDialog->signal_response().connect(sigc::mem_fun(*this, &photoflip::aboutResponse));
	
	// toolbar
	Gtk::ToolButton *toolButtonImport, *toolButtonBack, *toolButtonForward, *toolButtonZoomIn, *toolButtonZoomOut;
	
	refXml->get_widget("toolbar", m_toolbar);
	
	refXml->get_widget("toolButtonImport", toolButtonImport);
	toolButtonImport->signal_clicked().connect(sigc::mem_fun(*this, &photoflip::fileImport));
	
	refXml->get_widget("toolButtonBack", toolButtonBack);
	toolButtonBack->signal_clicked().connect(sigc::mem_fun(*this, &photoflip::back));

	refXml->get_widget("toolButtonForward", toolButtonForward);
	toolButtonForward->signal_clicked().connect(sigc::mem_fun(*this, &photoflip::forward));
	
	refXml->get_widget("toolButtonZoomIn", toolButtonZoomIn);
	toolButtonZoomIn->signal_clicked().connect(sigc::mem_fun(*this, &photoflip::zoomIn));
	
	refXml->get_widget("toolButtonZoomOut", toolButtonZoomOut);
	toolButtonZoomOut->signal_clicked().connect(sigc::mem_fun(*this, &photoflip::zoomOut));
	
	refXml->get_widget("toolButtonFullscreen", m_toolButtonFullscreen);
	m_toolButtonFullscreen->signal_toggled().connect(sigc::mem_fun(*this, &photoflip::fullscreen));
	
	// statusbar
	refXml->get_widget("statusbar", m_statusbar);
	
	// popup menu
	Gtk::RadioMenuItem *menuItemFrameNone;
	refXml->get_widget("menuView", m_popupMenuView);
	refXml->get_widget("menuPhoto", m_popupMenuPhoto);
	refXml->get_widget("menuFrame", m_menuFrame);
	refXml->get_widget("menuItemFrameNone", menuItemFrameNone);
	
	menuItemFrameNone->signal_activate().connect(sigc::bind(sigc::mem_fun(m_gl, &GLArea::setFrame), -1));
	
	m_gl.setPopupMenus(m_popupMenuView, m_popupMenuPhoto, m_menuFrame, menuItemFrameNone->get_group());
	
	// visualisation
	m_visu = new visuCircular(&m_lib);
	
	refXml->get_widget("menuItemVisuCircular", m_menuItemVisuCircular);
	m_menuItemVisuCircular->signal_activate().connect(sigc::mem_fun(*this, &photoflip::setVisualisation));
	
	refXml->get_widget("menuItemVisuStrew", m_menuItemVisuStrew);
	m_menuItemVisuStrew->signal_activate().connect(sigc::mem_fun(*this, &photoflip::setVisualisation));
		
	refXml->get_widget("menuItemVisuFold", m_menuItemVisuFold);
	m_menuItemVisuFold->signal_activate().connect(sigc::mem_fun(*this, &photoflip::setVisualisation));
	
	// GLArea attach & show
	Gtk::HBox *glBox = 0;
	refXml->get_widget("glBox", glBox);
	
	m_gl.set_flags(m_gl.get_flags() | Gtk::CAN_FOCUS);
	
	glBox->pack_start(m_gl);
	m_gl.setVisualisation(m_visu);
	m_gl.show();
}

photoflip::~photoflip() {
	delete m_visu;
	delete m_mainWindow;
	delete m_aboutDialog;
}

void photoflip::rien() {
	std::cout << "rien" << std::endl;
}

void photoflip::quit() {
	Gtk::Main::quit();
}
void photoflip::showControls() {
	if(m_menuItemShowControls->get_active()) {
		m_menuBar->show();
		m_toolbar->show();
		m_statusbar->show();
	} else {
		m_menuBar->hide();
		m_toolbar->hide();
		m_statusbar->hide();
	}
}

void photoflip::fileImport() {
	m_fileImportDialog->show();
}

void photoflip::fileImportResponse(int response) {
	//! \todo this function should start a thread and copy the files asynchroneously
	m_fileImportDialog->hide();
	
	if(response == Gtk::RESPONSE_CANCEL) return;
	
	std::vector<std::string> files = m_fileImportDialog->get_filenames();
	gchar *fileContents;
	gsize fileLength;
	
	for(std::vector<std::string>::iterator file = files.begin(); file != files.end(); file++) {
		std::string pathLibraryFile = Glib::build_filename(Glib::build_filename(Glib::get_home_dir(), ".photoflip"), "library");
		if(m_lib.inCollection()) pathLibraryFile = Glib::build_filename(pathLibraryFile, m_lib.getCollectionName());
		pathLibraryFile = Glib::build_filename(pathLibraryFile, Glib::path_get_basename(*file));
		
		if(g_file_get_contents((*file).c_str(), &fileContents, &fileLength, NULL)) {
			g_file_set_contents(pathLibraryFile.c_str(), fileContents, fileLength, NULL);
			g_free(fileContents); //! \todo is that right?
		}
	}
}

void photoflip::menuFullscreen() {
	m_toolButtonFullscreen->set_active(m_menuItemFullscreen->get_active());
	fullscreen();
}

void photoflip::fullscreen() {
	if(m_toolButtonFullscreen->get_active()) {
		m_mainWindow->fullscreen();
		m_toolButtonFullscreen->set_stock_id(Gtk::Stock::LEAVE_FULLSCREEN);
		m_menuItemFullscreen->set_active(true);
	} else {
		m_mainWindow->unfullscreen();
		m_toolButtonFullscreen->set_stock_id(Gtk::Stock::FULLSCREEN);
		m_menuItemFullscreen->set_active(false);
	}
}

void photoflip::setVisualisation() {
	float zoom = m_visu->getZoom();
	delete m_visu;
	m_visu = NULL;
		
	if(m_menuItemVisuCircular->get_active())
		m_visu = new visuCircular(&m_lib, m_menuItemShowFrames->get_active());
	else if(m_menuItemVisuStrew->get_active())
		m_visu = new visuStrew(&m_lib, m_menuItemShowFrames->get_active());
	else if(m_menuItemVisuFold->get_active())
		m_visu = new visuFold(&m_lib, m_menuItemShowFrames->get_active());
	
	m_gl.setVisualisation(m_visu);
	m_gl.setZoom(zoom);
	m_gl.setElement(0);
}

void photoflip::showFrames() {
	m_gl.showFrames(m_menuItemShowFrames->get_active());
}

void photoflip::deletePhoto() {
	if(m_lib.inCollection()) m_photoDeletionDialog->show();
}

void photoflip::deletePhotoResponse(int response) {
	m_photoDeletionDialog->hide();
	
	if(response == Gtk::RESPONSE_OK)
		m_gl.deletePhoto(-1);
}

void photoflip::about() {
	m_aboutDialog->show();
}

void photoflip::aboutResponse(int response) {
	m_aboutDialog->hide();
}

void photoflip::back() {
	m_gl.setElement(m_gl.getElement() - 1);
}

void photoflip::forward() {
	m_gl.setElement(m_gl.getElement() + 1);
}

void photoflip::zoomIn() {
	m_gl.setZoom(m_gl.getZoom() + 50.0f);
}

void photoflip::zoomOut() {
	m_gl.setZoom(m_gl.getZoom() - 50.0f);
}
